package cn.zn.modules.zzsys.cur.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.zn.framework.common.exception.RRException;
import cn.zn.modules.pz.inter.values.PzConf;
import cn.zn.modules.zzsys.cur.entity.PO.TeacherPgroupPO;
import cn.zn.modules.zzsys.cur.entity.PO.TeacherPgroupUserDeptPO;
import cn.zn.modules.zzsys.cur.entity.TSysDept;
import cn.zn.modules.zzsys.cur.entity.TeacherPgroup;
import cn.zn.modules.zzsys.cur.entity.dto.UserProcessGroupSaveDTO;
import cn.zn.modules.zzsys.cur.entity.vo.TeacherPgroupUserDeptItemVO;
import cn.zn.modules.zzsys.cur.entity.vo.TeacherPgroupUserDeptVO;
import cn.zn.modules.zzsys.cur.entity.vo.TeacherPgroupUserVO;
import cn.zn.modules.zzsys.cur.entity.vo.TeacherPgroupVO;
import cn.zn.modules.zzsys.cur.mapper.TeacherPgroupMapper;
import cn.zn.modules.zzsys.cur.service.TSysDeptService;
import cn.zn.modules.zzsys.cur.service.TeacherPgroupService;
import cn.zn.modules.zzsys.enums.ProcessGroupTypeEnum;
import cn.zn.modules.zzsys.enums.po.ProcessGroupPermissions;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.beust.jcommander.internal.Lists;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 *
 */
@Service
public class TeacherPgroupServiceImpl extends ServiceImpl<TeacherPgroupMapper, TeacherPgroup>
        implements TeacherPgroupService {
    @Autowired
    private PzConf pzConf;
    @Autowired
    private TSysDeptService tSysDeptService;

    @Override
    public List<TeacherPgroupVO> queryGroupList() {
        // 查询已设置信息
        Map<String, TeacherPgroupPO> poMap = this.baseMapper.queryProcessGroupAndUserNum().stream().collect(Collectors.toMap(TeacherPgroupPO::getGroupCode, o -> o));
        // 获取所有可设置信息
        ProcessGroupPermissions processGroupPermissions = new ProcessGroupPermissions();
        BeanUtils.copyProperties(pzConf.getProcess(), processGroupPermissions);
        // 整理返回数据
        return ProcessGroupTypeEnum.listForSetup(processGroupPermissions).stream().map(o -> {
            TeacherPgroupVO vo = new TeacherPgroupVO();
            BeanUtils.copyProperties(o, vo);
            vo.setGroupCode(o.getCode());
            vo.setGroupName(o.getName());
            // 填充已设置信息
            if (poMap.containsKey(o.getCode())) {
                vo.setUserNum(poMap.get(o.getCode()).getUserNum());
            }
            return vo;
        }).sorted(Comparator.comparingInt(TeacherPgroupVO::getSortNum)).collect(Collectors.toList());
    }

    @Override
    public List<TeacherPgroupUserVO> queryUserGroupList(String processGroupCode) {
        return this.baseMapper.queryProcessGroupForUserDept(processGroupCode).stream().map(o -> {
            TeacherPgroupUserVO vo = new TeacherPgroupUserVO();
            vo.setId(o.getId());
            vo.setGroupCode(o.getGroupCode());
            vo.setTeacherId(o.getTeacherId());
            vo.setTeacherName(o.getTeacherName());
            return vo;
        }).collect(Collectors.toList());
    }

    @Override
    public List<TeacherPgroupUserDeptVO> queryUserDeptGroupList(String processGroupCode) {
        // 查询出所有部门
        Map<String, TeacherPgroupUserDeptVO> voMap = tSysDeptService.queryForLeaf().stream().map(o -> {
            TeacherPgroupUserDeptVO vo = new TeacherPgroupUserDeptVO();
            vo.setDeptId(o.getId());
            vo.setDeptName(o.getDeptName());
            vo.setGroupCode(processGroupCode);
            vo.setGroupName(ProcessGroupTypeEnum.findByCode(processGroupCode).getName());
            return vo;
        }).collect(Collectors.toMap(TeacherPgroupUserDeptVO::getDeptId, o -> o, (o1, o2) -> o1, LinkedHashMap::new));
        this.baseMapper.queryProcessGroupForUserDept(processGroupCode).forEach(o -> {
            if (voMap.containsKey(o.getDeptId())) {
                voMap.get(o.getDeptId()).getItems().add(TeacherPgroupUserDeptItemVO.builder()
                        .teacherId(o.getTeacherId())
                        .teacherName(o.getTeacherName())
                        .build());
            }
        });
        return Lists.newArrayList(voMap.values());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveUserProcessGroup(UserProcessGroupSaveDTO dto, Boolean insteadDept, Boolean insteadProessGroup) {
        if (!StrUtil.isNotEmpty(dto.getProcessGroupCode())) {
            throw new RRException("保存失败，流程用户组编号不能为空");
        }
        ProcessGroupTypeEnum processGroupTypeEnum = ProcessGroupTypeEnum.findByCode(dto.getProcessGroupCode());
        if (processGroupTypeEnum == null) {
            throw new RRException(String.format("保存失败，流程用户组不存在:%s", dto.getProcessGroupCode()));
        }
        if (insteadDept != null && insteadDept) {
            if (!StrUtil.isNotEmpty(dto.getDeptId())) {
                throw new RRException("保存失败，部门ID不能为空");
            }
            // 删除某部门某流程用户组的所有人员
            super.remove(new QueryWrapper<TeacherPgroup>()
                    .eq("GROUP_", dto.getProcessGroupCode())
                    .eq("T_SYS_DEPT_ID_", dto.getDeptId()));
        }
        if (insteadProessGroup != null && insteadProessGroup) {
            // 删除某部门某流程用户组的所有人员
            super.remove(new QueryWrapper<TeacherPgroup>()
                    .eq("GROUP_", dto.getProcessGroupCode()));
        }
        // 保存
        dto.getTeacherIds().forEach(o -> {
            // 是否存在相同记录
            int count = super.count(new QueryWrapper<TeacherPgroup>()
                    .eq("GROUP_", dto.getProcessGroupCode())
                    .eq(StrUtil.isNotEmpty(dto.getDeptId()), "T_SYS_DEPT_ID_", dto.getDeptId())
                    .eq("T_TEACHER_INFO_ID_", o));
            if (count == 0) {
                TeacherPgroup teacherPgroup = new TeacherPgroup();
                teacherPgroup.setGroup(dto.getProcessGroupCode());
                teacherPgroup.setGroupName(processGroupTypeEnum.getName());
                teacherPgroup.setTTeacherInfoId(o);
                teacherPgroup.setTSysDeptId(dto.getDeptId());
                super.save(teacherPgroup);
            }
        });
    }
}




